package io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class GeneFileReader {
	private String[] m_genes;
	private String[] m_annotations;

	public GeneFileReader(InputStream input) throws IOException {
		m_annotations = null;
		m_genes = preProcessSourceLines(input);
	}

	public String getGeneAt(int index) {
		if (index < m_genes.length) {
			return m_genes[index];
		} else {
			throw new IllegalArgumentException("Illegal index of gene used..."
					+ index);
		}
	}

	public String getAnnotationAt(int index) {
		if (index < m_annotations.length) {
			return m_annotations[index];
		} else {
			throw new IllegalArgumentException(
					"Illegal index of annotation used..." + index);
		}
	}

	public int numberOfGenes() {
		return m_genes.length;
	}

	private boolean additionCheck(String geneToAdd) {
		int length = geneToAdd.length();

		if (length == 0) {
			return false;
		}

		String prefix = geneToAdd.substring(0, 3);
		String suffix = geneToAdd.substring(length - 3);

		if (!prefix.equalsIgnoreCase("ATG")
				|| (!suffix.equalsIgnoreCase("TAA")
						&& !suffix.equalsIgnoreCase("TAG") && !suffix
						.equalsIgnoreCase("TGA"))
						|| (geneToAdd.length() % 3 != 0)) {
			return false;
		}

		for (int i = 0; i < geneToAdd.length(); i++) {
			char x = geneToAdd.charAt(i);

			if ((x != 'A') && (x != 'T') && (x != 'C') && (x != 'G')) {
				return false;
			}
		}

		return true;
	}

	private String[] preProcessSourceLines(InputStream in) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		List lineList = new ArrayList();

		String ann = "";
		List annList = new ArrayList();

		String line;
		String extendedLine = "";
		int added = 0;
		int notAdded = 0;
		int i=0;

		while ((line = reader.readLine()) != null) {
			if (i==0){
				annList.add(line.substring(1));
				i++;
			}
			if ((line.length() > 0) && (line.charAt(0) != '>')) {
				line = line.trim();
				extendedLine = extendedLine.concat(line);
			} else {

				if ((line.length() > 0) && additionCheck(extendedLine)) {
					lineList.add(extendedLine.toUpperCase());
					annList.add(line.substring(1));
					added = added + 1;
					extendedLine = "";

				} else {
					if ((line.length() > 0) && !additionCheck(extendedLine)) {
						extendedLine = "";
						notAdded = notAdded + 1;
					}
				}
			}
		}

		if (additionCheck(extendedLine)) {
			lineList.add(extendedLine.toUpperCase());
			added = added + 1;
		} else {
			notAdded = notAdded + 1;
		}

		reader.close();

		// System.out.println("added="+ added);
		// System.out.println("not added="+ notAdded);

		m_annotations = (String[]) annList.toArray(new String[annList.size()]);
		return (String[]) lineList.toArray(new String[lineList.size()]);
	}
}
